/*
 * $Id$
 *
 * Copyright (C) 2008 Josh Guilfoyle <jasta@devtcg.org>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

package org.devtcg.five.music.service;

import org.devtcg.five.music.service.IPlaylistBufferListener;
import org.devtcg.five.music.service.IPlaylistMoveListener;

/**
 * IPC interface to manage the music player's background playlist.  The
 * playlist service itself is responsible for managing content downloads and
 * audio playback.
 *
 * Do not confuse this interface with a preconstructed playlist as synchronized
 * by Five.  Instead, this interface is the concrete playback engine for Five
 * Music.
 */
interface IPlaylistService
{
	int next();
	int previous();
	void jump(int pos);

	void play();
	void pause();
	void unpause();
	void stop();

	/**
	 * Watch the playlist for jump, advance, and song skip/seek.  Also covers
	 * start and stop.
	 *
	 * @param l
	 *   Playlist listener.
	 */
	void registerOnMoveListener(IPlaylistMoveListener l);
	void unregisterOnMoveListener(IPlaylistMoveListener l);

	/**
	 * Is the current song actively downloading?
	 */
	boolean isBuffering();

	/**
	 * Observe download progress of currently playing track.  If no track
	 * is currently active, no listener events will be fired (until that
	 * condition changes).  If playback is active or pending, will immediately
	 * invoke an update with the current progress even if buffering is
	 * complete.
	 *
	 * @param l
	 *   Buffer update listener.
	 */
	void registerOnBufferListener(IPlaylistBufferListener l);
	void unregisterOnBufferListener(IPlaylistBufferListener l);

	/**
	 * Seek within the currently playing song.
	 *
	 * @param pos
	 *   Seek position in seconds.
	 */
	void seek(long pos);
	void skip(long offs);

	/**
	 * Answers the current playing position.
	 *
	 * @return Current position in seconds.
	 */
	long tell();

	/**
	 * Determines if playback is active or pending.  Note that with Five,
	 * playback exists even when no audio is being sent to the speaker.  In
	 * this case, the song is being buffered and is not yet ready to be heard.
	 */
	boolean isPlaying();
	boolean isPaused();
	boolean isStopped();

	/**
	 * Access the current playlist.
	 *
	 * @return
	 *   List of song identifiers as specified by {@link Five.Music.Songs._ID}.
	 */
	List getPlaylist();
	List getPlaylistWindow(int from, int to);

	/**
	 * Get the currently playing song as a position in the playlist.
	 */
	int getPosition();
	long getSongAt(int position);

	/**
	 * Convenience method to check if a song is playing, has played, or is
	 * queued to play.  This method is a simple optimization to avoid calling
	 * getPlaylist and searching the list.
	 *
	 * @param songId
	 *   
	 * @return
	 *   True if the song is in the current playlist; false otherwise.
	 */
	boolean isInPlaylist(long songId);

	/**
	 * Get the currently playing song's duration.
	 *
	 * @return
	 *   The duration in seconds if playback is active; otherwise, -1.
	 */
	int getSongDuration();

	/**
	 * Get the currently playing song's playback position.
	 * 
	 * @return
	 *   Position in seconds if playback is active; otherwise, -1.
	 */
	int getSongPosition();

	int insert(long songId, int position);
	int insertAlbum(long albumId, int position);
	int insertArtist(long artistId, int position);

	int enqueueAndPlay(long songId);
	int enqueue(long songId);
	int enqueueAlbum(long songId);
	int enqueueArtist(long songId);

	/**
	 * Places the song next in the play queue and attempts playback
	 * immediately.
	 */
	int enqueueNextAndPlay(long songId);
	int enqueueNext(long songId);

	void remove(long songId);

	/**
	 * Deletes all implied playlist items.  Implied items are those that have
	 * not been specifically selected by 
	 */
	void tidy();

	void shuffle();

	void setRepeat(boolean repeat);
	void setRandom(boolean random);
	void setAdvance(boolean advance);
}
